﻿using CIS.DB;
using CIS.Web.Common;
using CIS.Web.Models;
using CIS.Web.Properties;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Linq.Dynamic;
using System.Threading.Tasks;
using System.Web.Mvc;
using static System.Net.Mime.MediaTypeNames;

namespace CIS.Web.Controllers
{
	[RoutePrefix("ConferenceQuiz")]
	public class ConferenceQuizController : BaseDbController
	{
		[Route("Index/{ConferenceId}")]
		public async Task<ActionResult> Index(string conferenceId)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", conferenceId);

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
						x.ID == conferenceId);

			ViewBag.ConferenceId = conferenceId;
			ViewBag.ConferenceName = conferenceMaster.ConferenceName;
			ViewBag.ControllerName = Resources.ConferenceQuiz;
			ViewBag.Language = conferenceMaster.IsInternational ? ConstValues.Language.En : ConstValues.Language.Cn;

			var model = new ConferenceQuizModel();
			model.ConferenceId = conferenceId;
			LoginUser.ConferenceFunctionIdList = Utility.GetConferenceFunctionIdList(conferenceId);
			return View(model);
		}

		public async Task<JsonCamelCaseResult> GetData(int? page, int? rows, string sort, string order, ConferenceQuizModel model)
		{
			int take = rows ?? ConstValues.DefaultGridRows;
			int skip = ((page ?? 1) - 1) * take;

			var sql = DbContext.QuizMaster.AsNoTracking()
					.Where(x => !string.IsNullOrEmpty(x.Status) &&
						x.ConferenceId == model.ConferenceId);

			if (!string.IsNullOrWhiteSpace(model.SelQuizName))
			{
				sql = sql.Where(x => x.QuizName.Contains(model.SelQuizName));
			}

			int total = await sql.CountAsync();

			if (!string.IsNullOrEmpty(sort))
			{
				sql = sql.OrderBy(sort + ConstValues.chrSpace + order).Skip(skip).Take(take);
			}
			else
			{
				sql = sql.OrderBy(x => x.Sort).ThenByDescending(x => x.UpdateDate).ThenBy(x => x.QuizName).Skip(skip).Take(take);
			}

			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				ID = x.ID,
				ConferenceId = x.ConferenceId,
				QuizName = x.QuizName,
				Status = x.Status,
				Sort = x.Sort,
				Remark = x.Remark,
				Creator = x.Creator,
				CreateIP = x.CreateIP,
				CreateDate = Request.Cookies["_culture"].Value == ConstValues.Language.Cn ?
							x.CreateDate.Value.ToString("yyyy-MM-dd") :
							x.CreateDate.Value.ToString("MM/dd/yyyy")
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetEditData(string id)
		{
			var result = await DbContext.QuizMaster.AsNoTracking().FirstOrDefaultAsync(x => x.ID == id);

			if (result != null)
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(string.Empty, result),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("Create/{ConferenceId}")]
		public async Task<JsonResult> Create(ConferenceQuizModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.QuizMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ConferenceId == model.ConferenceId &&
						x.QuizName == model.QuizName);

			if (result != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.QuizName)),
						JsonRequestBehavior.AllowGet);
			}

			var quizMaster = new QuizMaster
			{
				ID = Utility.GetTableId(ConstValues.TableName.QuizMaster),
				ConferenceId = model.ConferenceId,
				QuizName = model.QuizName,
				Status = model.Status,
				Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort,
				Remark = model.Remark?.Trim(),
				Creator = LoginUser.UserName,
				CreateIP = LoginUser.IP,
				CreateDate = DateTime.Now
			};

			DbContext.QuizMaster.Add(quizMaster);
			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("Modify/{ConferenceId}")]
		public async Task<JsonResult> Modify(ConferenceQuizModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var exist = await DbContext.QuizMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID != model.Id &&
						x.ConferenceId == model.ConferenceId &&
						x.QuizName == model.QuizName);

			if (exist != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.QuizName)),
						JsonRequestBehavior.AllowGet);
			}

			var result = await DbContext.QuizMaster
					.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result != null)
			{
				result.QuizName = model.QuizName?.Trim();
				result.Status = model.Status;
				result.Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort;
				result.Remark = model.Remark?.Trim();
				result.Updater = LoginUser.UserName;
				result.UpdateIP = LoginUser.IP;
				result.UpdateDate = DateTime.Now;

				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("Delete/{ConferenceId}")]
		public async Task<JsonResult> Delete(ConferenceQuizModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var exist = await DbContext.ProfileQuizInfo.AsNoTracking()
					.Where(x => x.QuizId == model.Id).ToListAsync();

			if (exist.Count > 0)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgUsingCanNotDelete),
						JsonRequestBehavior.AllowGet);
			}

			var result = await DbContext.QuizMaster
					.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result != null)
			{
				using (var transaction = DbContext.Database.BeginTransaction())
				{
					DbContext.QuizMaster.Remove(result);

					var questionMasterList = await DbContext.QuestionMaster
							.Where(x => x.QuizId == model.Id).ToListAsync();
					DbContext.QuestionMaster.RemoveRange(questionMasterList);

					var answerMasterList = await DbContext.AnswerMaster
							.Where(x => x.QuizId == model.Id).ToListAsync();
					DbContext.AnswerMaster.RemoveRange(answerMasterList);

					await DbContext.SaveChangesAsync();
					transaction.Commit();
				}

				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessDelete),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		public async Task<JsonCamelCaseResult> GetQuestionData(string quizId)
		{
			var sql = DbContext.QuestionMaster.AsNoTracking()
					.Where(x => x.QuizId == quizId)
					.OrderBy(x => x.QuestionType)
					.ThenBy(x => x.Sort)
					.ThenBy(x => x.QuestionName)
					.ThenByDescending(x => x.UpdateDate);

			var result = await sql.ToListAsync();

			return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetEditQuestionData(string id)
		{
			var result = await DbContext.QuestionMaster.AsNoTracking().FirstOrDefaultAsync(x => x.ID == id);

			if (result != null)
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(string.Empty, result),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("CreateQuestion/{ConferenceId}")]
		public async Task<JsonResult> CreateQuestion(ConferenceQuizModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var exist = await DbContext.QuestionMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ConferenceId == model.ConferenceId &&
						x.QuizId == model.QuizId &&
						x.QuestionName == model.QuestionName);

			if (exist != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.QuestionName)),
						JsonRequestBehavior.AllowGet);
			}

			var questionMaster = new QuestionMaster
			{
				ID = Utility.GetTableId(ConstValues.TableName.QuestionMaster),
				ConferenceId = model.ConferenceId,
				QuizId = model.QuizId,
				QuestionType = model.QuestionType,
				QuestionName = model.QuestionName,
				Status = model.Status,
				Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort,
				Remark = model.Remark?.Trim(),
				Creator = LoginUser.UserName,
				CreateIP = LoginUser.IP,
				CreateDate = DateTime.Now
			};

			DbContext.QuestionMaster.Add(questionMaster);
			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("ModifyQuestion/{ConferenceId}")]
		public async Task<JsonResult> ModifyQuestion(ConferenceQuizModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var exist = await DbContext.QuestionMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID != model.QuestionId &&
						x.ConferenceId == model.ConferenceId &&
						x.QuizId == model.QuizId &&
						x.QuestionName == model.QuestionName);

			if (exist != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.QuestionName)),
						JsonRequestBehavior.AllowGet);
			}

			var result = await DbContext.QuestionMaster.FirstOrDefaultAsync(x => x.ID == model.QuestionId);

			if (result != null)
			{
				result.QuestionName = model.QuestionName;
				result.QuestionType = model.QuestionType;
				result.Status = model.Status;
				result.Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort;
				result.Remark = model.Remark?.Trim();
				result.Updater = LoginUser.UserName;
				result.UpdateIP = LoginUser.IP;
				result.UpdateDate = DateTime.Now;

				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("DeleteQuestion/{ConferenceId}")]
		public async Task<JsonResult> DeleteQuestion(ConferenceQuizModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.QuestionMaster
					.FirstOrDefaultAsync(x => x.ID == model.QuestionId);

			if (result != null)
			{
				using (var transaction = DbContext.Database.BeginTransaction())
				{
					DbContext.QuestionMaster.Remove(result);

					var answerMasterList = await DbContext.AnswerMaster
							.Where(x => x.QuestionId == model.QuestionId).ToListAsync();
					DbContext.AnswerMaster.RemoveRange(answerMasterList);

					await DbContext.SaveChangesAsync();
					transaction.Commit();
				}

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessDelete),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		public async Task<JsonCamelCaseResult> GetAnswerData(string questionId)
		{
			var sql = DbContext.AnswerMaster.AsNoTracking()
					.Where(x => x.QuestionId == questionId)
					.OrderBy(x => x.Sort)
					.ThenBy(x => x.Answer)
					.ThenByDescending(x => x.UpdateDate);

			var result = await sql.ToListAsync();

			return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetEditAnswerData(string id)
		{
			var result = await DbContext.AnswerMaster.AsNoTracking().FirstOrDefaultAsync(x => x.ID == id);

			if (result != null)
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(string.Empty, result),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("CreateAnswer/{ConferenceId}")]
		public async Task<JsonResult> CreateAnswer(ConferenceQuizModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var exist = await DbContext.AnswerMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ConferenceId == model.ConferenceId &&
						x.QuestionId == model.QuestionId &&
						x.QuizId == model.QuizId &&
						x.Answer == model.Answer);

			if (exist != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.Answer)),
						JsonRequestBehavior.AllowGet);
			}

			var answerMaster = new AnswerMaster
			{
				ID = Utility.GetTableId(ConstValues.TableName.AnswerMaster),
				ConferenceId = model.ConferenceId,
				QuizId = model.QuizId,
				QuestionId = model.QuestionId,
				Answer = model.Answer,
				IsCorrect = false,
				Status = model.Status,
				Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort,
				Remark = model.Remark?.Trim(),
				Creator = LoginUser.UserName,
				CreateIP = LoginUser.IP,
				CreateDate = DateTime.Now
			};

			DbContext.AnswerMaster.Add(answerMaster);
			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("ModifyAnswer/{ConferenceId}")]
		public async Task<JsonResult> ModifyAnswer(ConferenceQuizModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var exist = await DbContext.AnswerMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID != model.AnswerId &&
						x.ConferenceId == model.ConferenceId &&
						x.QuestionId == model.QuestionId &&
						x.QuizId == model.QuizId &&
						x.Answer == model.Answer);

			if (exist != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.Answer)),
						JsonRequestBehavior.AllowGet);
			}

			var result = await DbContext.AnswerMaster.FirstOrDefaultAsync(x => x.ID == model.AnswerId);

			if (result != null)
			{
				result.Answer = model.Answer;
				result.Status = model.Status;
				result.Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort;
				result.Remark = model.Remark?.Trim();
				result.Updater = LoginUser.UserName;
				result.UpdateIP = LoginUser.IP;
				result.UpdateDate = DateTime.Now;

				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("DeleteAnswer/{ConferenceId}")]
		public async Task<JsonResult> DeleteAnswer(ConferenceQuizModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.AnswerMaster
					.FirstOrDefaultAsync(x => x.ID == model.AnswerId);

			if (result != null)
			{
				DbContext.AnswerMaster.Remove(result);

				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessDelete),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<FileResult> Export(string conferenceId, string quizId)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", conferenceId);

			var ids = quizId.Split(ConstValues.chrComma);
			var sqlChoice = from quizMaster in DbContext.QuizMaster.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常 &&
						ids.Contains(x.ID.ToString()))
					join questionMaster in DbContext.QuestionMaster.AsNoTracking()
					      .Where(x => x.Status == ConstValues.Status.正常 &&
						      (x.QuestionType == ConstValues.QuestionType.单选题 ||
						      x.QuestionType == ConstValues.QuestionType.多选题))
						on quizMaster.ID equals questionMaster.QuizId
					join answerMaster in DbContext.AnswerMaster.AsNoTracking()
						      .Where(x => x.Status == ConstValues.Status.正常)
						on questionMaster.ID equals answerMaster.QuestionId into answers
					from answer in answers.DefaultIfEmpty()
					join feedbackInfo in DbContext.FeedbackInfo.AsNoTracking()
					      .Where(x => x.Status == ConstValues.Status.正常)
					      .GroupBy(x => x.Feedback).Select(x => new
					      {
						      Feedback = x.Key,
						      Cnt = x.Count()
					      })
						on answer.ID equals feedbackInfo.Feedback into feedbacks
					from feedback in feedbacks.DefaultIfEmpty()
					orderby questionMaster.QuestionType, questionMaster.Sort, answer.Sort, answer.CreateDate
					select new
					{
						QuizName = quizMaster.QuizName,
						QuestionId = questionMaster.ID,
						QuestionType = questionMaster.QuestionType,
						QuestionName = questionMaster.QuestionName,
						AnswerId = answer.ID,
						Answer = answer.Answer,
						Cnt = feedback != null ? feedback.Cnt : 0
					};

			var resultChoice = await sqlChoice.ToListAsync();

			var sqlEssay = from quizMaster in DbContext.QuizMaster.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常 &&
						ids.Contains(x.ID.ToString()))
				       join questionMaster in DbContext.QuestionMaster.AsNoTracking()
					     .Where(x => x.Status == ConstValues.Status.正常 &&
						     x.QuestionType == ConstValues.QuestionType.填空题)
					       on quizMaster.ID equals questionMaster.QuizId
				       join feedbackInfo in DbContext.FeedbackInfo.AsNoTracking()
					     .Where(x => x.Status == ConstValues.Status.正常)
					      on questionMaster.ID equals feedbackInfo.QuestionId into feedbacks
				       from feedback in feedbacks.DefaultIfEmpty()
				       orderby questionMaster.QuestionType, questionMaster.Sort, feedback.CreateDate
				       select new
				       {
					       QuizName = quizMaster.QuizName,
					       QuestionId = questionMaster.ID,
					       QuestionType = questionMaster.QuestionType,
					       QuestionName = questionMaster.QuestionName,
					       Answer = feedback.Feedback
				       };

			var resultEssay = await sqlEssay.ToListAsync();

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID == conferenceId &&
						x.Status == ConstValues.Status.正常);

			var export = conferenceMaster.IsInternational ?
					Resources.export_quizEN :
					Resources.export_quizCN;

			XSSFWorkbook workbook;

			using (MemoryStream readStream = new MemoryStream(export))
			{
				workbook = new XSSFWorkbook(readStream);
				ISheet sheet = workbook.GetSheetAt(0);
				IRow row = sheet.CreateRow(0);
				row.Height = 60 * 20;

				ICellStyle style = workbook.CreateCellStyle();
				style.Alignment = HorizontalAlignment.Center;
				style.VerticalAlignment = VerticalAlignment.Center;
				IFont font = workbook.CreateFont();
				font.FontHeight = 20;
				style.SetFont(font);

				ICell cell = row.CreateCell(0);
				cell.SetCellValue(resultChoice.FirstOrDefault()?.QuizName);
				cell.CellStyle = style;

				var countChoice = 1;
				var questionTypeChoiceIndex = 2;
				var questionNameChoiceIndex = 2;

				for (var index = 0; index < resultChoice.Count; index++)
				{
					countChoice += 1;
					row = sheet.CreateRow(countChoice);

					//QuestionType
					int column = 0;
					cell = row.CreateCell(column);
					if (index == 0)
					{
						cell.SetCellValue(!string.IsNullOrEmpty(resultChoice[index].QuestionType) ? resultChoice[index].QuestionType : string.Empty);
						style = workbook.CreateCellStyle();
						style.VerticalAlignment = VerticalAlignment.Center;
						style.WrapText = true;
						cell.CellStyle = style;
					}
					else
					{
						if (resultChoice[index].QuestionType != resultChoice[index - 1].QuestionType)
						{
							cell.SetCellValue(!string.IsNullOrEmpty(resultChoice[index].QuestionType) ? resultChoice[index].QuestionType : string.Empty);
							style = workbook.CreateCellStyle();
							style.VerticalAlignment = VerticalAlignment.Center;
							style.WrapText = true;
							cell.CellStyle = style;

							sheet.AddMergedRegion(new CellRangeAddress(questionTypeChoiceIndex, index + 1, 0, 0));
							questionTypeChoiceIndex = index + 2;
						}
						else
						{
							cell.SetCellValue(string.Empty);
						}
					}

					//QuestionName
					column++;
					cell = row.CreateCell(column);
					if (index == 0)
					{
						cell.SetCellValue(!string.IsNullOrEmpty(resultChoice[index].QuestionName) ? resultChoice[index].QuestionName : string.Empty);
						style = workbook.CreateCellStyle();
						style.VerticalAlignment = VerticalAlignment.Center;
						style.WrapText = true;
						cell.CellStyle = style;
					}
					else
					{
						if (resultChoice[index].QuestionId != resultChoice[index - 1].QuestionId)
						{
							cell.SetCellValue(!string.IsNullOrEmpty(resultChoice[index].QuestionName) ? resultChoice[index].QuestionName : string.Empty);
							style = workbook.CreateCellStyle();
							style.VerticalAlignment = VerticalAlignment.Center;
							style.WrapText = true;
							cell.CellStyle = style;

							sheet.AddMergedRegion(new CellRangeAddress(questionNameChoiceIndex, index + 1, 1, 1));
							questionNameChoiceIndex = index + 2;
						}
						else
						{
							cell.SetCellValue(string.Empty);
						}
					}

					//Answer
					column++;
					cell = row.CreateCell(column);
					cell.SetCellValue(!string.IsNullOrEmpty(resultChoice[index].Answer) ? resultChoice[index].Answer.ToString() : string.Empty);

					//Cnt
					column++;
					cell = row.CreateCell(column);
					cell.SetCellValue(resultChoice[index].Cnt);

					if (index == resultChoice.Count - 1)
					{
						sheet.AddMergedRegion(new CellRangeAddress(questionTypeChoiceIndex, resultChoice.Count + 1, 0, 0));
						sheet.AddMergedRegion(new CellRangeAddress(questionNameChoiceIndex, resultChoice.Count + 1, 1, 1));
					}
				}

				ISheet sheet2 = workbook.GetSheetAt(1);
				IRow row2 = sheet2.CreateRow(0);
				row2.Height = 60 * 20;

				ICellStyle style2 = workbook.CreateCellStyle();
				style2.Alignment = HorizontalAlignment.Center;
				style2.VerticalAlignment = VerticalAlignment.Center;
				IFont font2 = workbook.CreateFont();
				font2.FontHeight = 20;
				style2.SetFont(font2);

				ICell cell2 = row2.CreateCell(0);
				cell2.SetCellValue(resultChoice.FirstOrDefault()?.QuizName);
				cell2.CellStyle = style2;

				var countEssay = 1;
				var questionTypeEssayIndex = 2;
				var questionNameEssayIndex = 2;

				for (var index = 0; index < resultEssay.Count; index++)
				{
					countEssay += 1;
					row2 = sheet2.CreateRow(countEssay);

					//QuestionType
					int column = 0;
					cell2 = row2.CreateCell(column);
					if (index == 0)
					{
						cell2.SetCellValue(!string.IsNullOrEmpty(resultEssay[index].QuestionType) ? resultEssay[index].QuestionType : string.Empty);
						style2 = workbook.CreateCellStyle();
						style2.VerticalAlignment = VerticalAlignment.Center;
						style2.WrapText = true;
						cell2.CellStyle = style2;
					}
					else
					{
						if (resultEssay[index].QuestionType != resultEssay[index - 1].QuestionType)
						{
							cell2.SetCellValue(!string.IsNullOrEmpty(resultEssay[index].QuestionType) ? resultEssay[index].QuestionType : string.Empty);
							style2 = workbook.CreateCellStyle();
							style2.VerticalAlignment = VerticalAlignment.Center;
							style2.WrapText = true;
							cell2.CellStyle = style2;

							sheet2.AddMergedRegion(new CellRangeAddress(questionTypeEssayIndex, index + 1, 0, 0));
							questionTypeEssayIndex = index + 2;
						}
						else
						{
							cell2.SetCellValue(string.Empty);
						}
					}

					//QuestionName
					column++;
					cell2 = row2.CreateCell(column);
					if (index == 0)
					{
						cell2.SetCellValue(!string.IsNullOrEmpty(resultEssay[index].QuestionName) ? resultEssay[index].QuestionName : string.Empty);
						style2 = workbook.CreateCellStyle();
						style2.VerticalAlignment = VerticalAlignment.Center;
						style2.WrapText = true;
						cell2.CellStyle = style2;
					}
					else
					{
						if (resultEssay[index].QuestionId != resultEssay[index - 1].QuestionId)
						{
							cell2.SetCellValue(!string.IsNullOrEmpty(resultEssay[index].QuestionName) ? resultEssay[index].QuestionName : string.Empty);
							style2 = workbook.CreateCellStyle();
							style2.VerticalAlignment = VerticalAlignment.Center;
							style2.WrapText = true;
							cell2.CellStyle = style2;

							sheet2.AddMergedRegion(new CellRangeAddress(questionNameEssayIndex, index + 1, 1, 1));
							questionNameEssayIndex = index + 2;
						}
						else
						{
							cell2.SetCellValue(string.Empty);
						}
					}

					//Answer
					column++;
					cell2 = row2.CreateCell(column);
					cell2.SetCellValue(resultEssay[index].Answer?.ToString());

					if (index == resultEssay.Count - 1)
					{
						sheet2.AddMergedRegion(new CellRangeAddress(questionTypeEssayIndex, resultEssay.Count + 1, 0, 0));
						sheet2.AddMergedRegion(new CellRangeAddress(questionNameEssayIndex, resultEssay.Count + 1, 1, 1));
					}
				}
			}

			MemoryStream exportStream = new MemoryStream();
			workbook.Write(exportStream);
			exportStream.Flush();
			exportStream.Position = 0;

			return File(exportStream, Application.Octet,
					$"export_quiz_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx");
		}
	}
}